/* PRQA S 3108++ */
/**
 * Copyright (C) 2008-2025 isoft Infrastructure Software Co., Ltd.
 * SPDX-License-Identifier: LGPL-2.1-only-with-exception
 *
 * This library is free software; you can redistribute it and/or modify it under the terms of the
 * GNU Lesser General Public License as published by the Free Software Foundation; version 2.1.
 * This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 * See the GNU Lesser General Public License for more details.
 * You should have received a copy of the GNU Lesser General Public License along with this library;
 * if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 * or see <https://www.gnu.org/licenses/>.
 */
/* PRQA S 3108-- */
/*
************************************************************************************************************************
**                                                                                                                    **
**  FILENAME    : TcpIp.c                                                                                             **
**                                                                                                                    **
**  Created on  : 03/12/18                                                                                            **
**  Author      : darren.zhang                                                                                        **
**  Vendor      :                                                                                                     **
**  DESCRIPTION : none                                                                                                **
**                                                                                                                    **
**  SPECIFICATION(S) :   AUTOSAR classic Platform R19-11                                                              **
**                                                                                                                    **
***********************************************************************************************************************/

/***********************************************************************************************************************
**                                          REVISION   HISTORY                                                        **
***********************************************************************************************************************/
/* <VERSION>    <DATE>       <AUTHOR>        <REVISION LOG>
 *  V1.0.0    [20190813]  [zhengfei.li]   Initial version
 *  V1.0.1    [20191129]  [zhengfei.li]   Through QAC testing, improve the code
 *  V1.0.2    [20191204]  [zhengfei.li]   When call TcpIp_RequestComMode(OFFLINE),  don't just change the socket
 *                                          state,need to free the lwip relate pcb.
 *  V1.0.3    [20191231]  [zhengfei.li]   UDP need to think about same port for UNICAST and MULTICAST
 *                                          (SD need the function).
 *  V1.0.4    [20200103]  [zhengfei.li]   Modify the lwip period timer handle bug
 *  V1.0.5    [20200107]  [zhengfei.li]   TcpIp_TcpErrCallback not to close the socket, the job is done by SoAd.
 *  V1.0.6    [20200110]  [zhengfei.li]   the lwip API udp_connect will connect the pcb with one specific
 *                                          remote address,will lead the pcb can't receive message from
 *                                          other remote note.
 *  V1.0.7    [20200115]  [zhengfei.li]   Solve different configurations cause compilation errors.
 *  V2.0.0    [20200828]  [pengfei.zhu]   Update to R19-11. Tcp/Udp_CopyTxData now have synchronous process.
 *                                          Add Tcp_Tls function. Add Enable/Disable Nagle algorithm of newPcb
 *                                          generated by listenPcb in TcpIp_TcpAcceptCallcback.
 *  V2.0.1    [20200928]  [pengfei.zhu]   QAC test.
 *  V2.0.2    [20210817]  [darren.zhang]  Code refactoring ,include code style and tls handle
 *  V2.0.3    [20220802]  [darren.zhang]  1.create tcp or udp socket add schm protect.
 *                                        2.default open ETHERNET_CHECK,avoid exceptions caused by
 *                                          ethIF return failure.
 *  V2.0.4    [20221020]  [darren.zhang]  add tc8 test api
 *  V2.0.5    [20221118]  [darren.zhang]  pbuf is abnormal because arp sending is interrupted by receiving interruption
 *  V2.0.6    [20221121]  [fupeng.yu]     merge BsdTcpIp
 *  V2.0.7    [20221121]  [darren.zhang]  Features:support socket vlan
 *  V2.0.8    [20230206]  [darren.zhang]  tcp socket option SocketTcpKeepAliveProbesMax data type conversion modify
 *  V2.0.9    [20230527]  [darren.zhang]  1.ethernet.c call EthIf_Transmit input parameter modify (CPT-439)
 *                                        2.tcp tp transmit handle logical adjustments when the buffer runs out
 *  V2.0.10   [20230725]  [darren.zhang]  1.lwip:reslove the response mismatch on the multi-network port tcp server
 *                                        2.lwip:etharp.c support only static arp
 *  V2.0.11   [20230801]  [fupeng.yu]     add TcpIp_TcpShutdown for tc8 test
 *  V2.0.12   [20230802]  [fupeng.yu]     TcpIp_Internal.c In TcpIp_PeriodTimerMainHandle,Modify the logic of period
 *                                        processing,resolve the period is inaccurate
 *  V2.0.13   [20230804]  [fupeng.yu]     TcpIp_Internal.c add TcpIp_GetControlIpFramePriority for the priority for all
 *                                        outgoing frames
 *  V2.0.14   [20230814]  [fupeng.yu]     1. TcpIp_Internal.c In TcpIp_UdpTransmitLocalIpCompare,Modify conditional
 *                                        compilation
 *                                        2. Resolve QAC
 *  V2.0.15   [20230816]  [fupeng.yu]     TcpIp_Internal.c In TcpIp_MallocTcpSocketIdByPcb,Resolve the socketflag of tcp
 *                                        server is modified by new created socket
 *  V2.0.16   [20230828]  [fupeng.yu]     1. TcpIp_Internal.c Modify the judgment conditions of netif->name[1] in
 *                                           TCPIP_CHECK_NETIF_ETHIF_CTRLINDEX
 *                                        2. TcpIp.c Add mapping EthIf CtrlIdx to TcpIp CtrlIdx
 *  V2.0.17   [20230925]  [darren.zhang]  1.support ipref2
 *                                        2.tcp tc8 empty ack modify
 *                                        3.delete half close tcp macro define
 *                                        4.support ip header set df bit
 *  V2.0.18   [20231207]  [fupeng.yu]     1. TcpIp_Internal.c Check the validity of the IP address when clearing
 *                                        the local IP address in TcpIp_ClearLocalAdrIpVar
 *                                        2. TcpIp_Internal.c Check the validity of IP address when forcibly
 *                                        notifying upper layers and the ipAdrState is ASSIGNED
 *                                        in TcpIp_CtrlLinkLocalAddrChagneHandle
 *  V2.0.19   [20231207]  [fupeng.yu]     TcpIp_Internal.c report runtime error when the return value of
 *                                        bind() is ERR_USE in TcpIp_InnerBind
 *  V2.0.20   [20240129]  [fupeng.yu]     1. supported localAddrId is TCPIP_LOCALADDRID_ANY for tcpip_bind()
 *  V2.0.21   [20240502]  [fupeng.yu]     1.support configuration of static arp table
 *  V2.0.22   [20240509]  [fupeng.yu]     Remove nesting of the same exclusive area
 *  V2.0.23   [20240618]  [darren.zhang]  modify bsd tcpip used schm
 *  V2.0.24   [20240624]  [fupeng.yu]     TcpIp_Internal.c resolve incorrect calculation of netmask in
 *                                        TcpIp_NetMaskInnerToExt
 *  V2.0.25   [20240712]  [fupeng.yu]     Modify obtaining TCP closed status for TC8 test
 *  V2.0.26   [20240725]  [fupeng.yu]     check the configuration of static ARP during initialization
 *  V2.0.27   [20240729]  [fupeng.yu]     move the posiition of the TCPIP_LOCALADR_CLR_IPVALID in
 *                                        TcpIp_ClearLocalAdrIpVar
 *  V2.0.28   [20240814]  [fupeng.yu]     modify transmission of TP for the TcpTransmit
 *  V2.0.29   [20240914]  [fupeng.yu]     Modify the pre-compilation condition for fast transmission of TCP data.
 *  V2.0.30   [20250506]  [fupeng.yu]     1.Resolve UDP port reuse for different TcpIp Controller.
 *                                        2.Modify the pre-compilation condition of TcpIp_InitState.
 **********************************************************************************************************************/
/**
 \page ISOFT_MISRA_Exceptions  MISRA-C:2012 Compliance Exceptions
   ModeName:TcpIp<br>
 RuleSorce:puhua-rule2024-2.rcf 2.3.5

   \li PRQA S 0605,3218 MISRA Rule 1.1 8.9 .<br>
   Reason:No impact was assessed and the status quo was maintained.

   \li PRQA S 3469,3472 MISRA Dir 4.9 .<br>
   Reason: Function-like macro are used to improve maintainability code.

*/
/***********************************************************************************************************************
 *  INCLUDES
 ***********************************************************************************************************************/
#include "TcpIp.h"
#include "TcpIp_Lcfg.h"
#if (STD_ON == TCPIP_DEM_SUPPORT)
#include "Dem.h"
#endif /*STD_ON == TCPIP_DEM_SUPPORT*/
#include "TcpIp_PBcfg.h"
#if (STD_ON == TCPIP_BSDSOCKET_SUPPORT)
#include "TcpIp_BsdInternal.h"
#else /* STD_ON != TCPIP_BSDSOCKET_SUPPORT */
#include "TcpIp_Internal.h"
#include "EthIf.h"
#endif /* STD_ON == TCPIP_BSDSOCKET_SUPPORT */
/***********************************************************************************************************************
 *  LOCAL DATA TYPES AND STRUCTURES
 ***********************************************************************************************************************/
/***********************************************************************************************************************
 *  LOCAL CONSTANT MACROS
 ***********************************************************************************************************************/
/* function parameter check level,per level consume memory or cycles is different */
#if !defined(TCPIP_PARA_CHECK_TAG)
#define TCPIP_PARA_CHECK
#define TCPIP_PARA_CHECK_OUTPUT(...) TCPIP_CHECK_OUTPUT(__VA_ARGS__)
#endif /* defined(TCPIP_INNER_CHECK_TAG) */
/***********************************************************************************************************************
 *  LOCAL DATA
 ***********************************************************************************************************************/
#define TCPIP_START_SEC_VAR_INIT_8
#include "TcpIp_MemMap.h"
TCPIP_LOCAL VAR(TcpIp_InitStateType, TCPIP_VAR_ZERO_INIT) TcpIp_InitState = TCPIP_STATE_UNINIT;
#define TCPIP_STOP_SEC_VAR_INIT_8
#include "TcpIp_MemMap.h"

#define TCPIP_START_SEC_VAR_CLEARED_PTR
#include "TcpIp_MemMap.h"
TCPIP_LOCAL P2CONST(TcpIp_ConfigType, AUTOMATIC, TCPIP_VAR) TcpIp_PbCfgPtr;
#define TCPIP_STOP_SEC_VAR_CLEARED_PTR
#include "TcpIp_MemMap.h"

/***********************************************************************************************************************
**                                              Version                                                               **
***********************************************************************************************************************/
#define TCPIP_C_AR_MAJOR_VERSION       4
#define TCPIP_C_AR_MINOR_VERSION       5
#define TCPIP_C_AR_PATCH_VERSION       0
#define TCPIP_C_SW_MAJOR_VERSION       2
#define TCPIP_C_SW_MINOR_VERSION       0
#define TCPIP_C_SW_PATCH_VERSION       30
#define TCPIP_SW_CFG_DEP_MAJOR_VERSION 2
#define TCPIP_SW_CFG_DEP_MINOR_VERSION 0
#define TCPIP_SW_CFG_DEP_PATCH_VERSION 0

/***********************************************************************************************************************
 *  VERSION CHECK
 ***********************************************************************************************************************/
/* check the version of TcpIp header files */
#if (                                                                                                                \
    (TCPIP_C_AR_MAJOR_VERSION != TCPIP_H_AR_MAJOR_VERSION) || (TCPIP_C_AR_MINOR_VERSION != TCPIP_H_AR_MINOR_VERSION) \
    || (TCPIP_C_AR_PATCH_VERSION != TCPIP_H_AR_PATCH_VERSION))
#error "version numbers of TcpIp.h and TcpIp.c are inconsistent"
#endif

/* check the version of the configuration header file */
#if (                                                          \
    (TCPIP_C_AR_MAJOR_VERSION != TCPIP_CFG_H_AR_MAJOR_VERSION) \
    || (TCPIP_C_AR_MINOR_VERSION != TCPIP_CFG_H_AR_MINOR_VERSION))
#error "version numbers of TcpIp_Cfg.h and TcpIp.c are inconsistent"
#endif

/* check config depend on version identification */
#if (                                                                   \
    (TCPIP_SW_CFG_DEP_MAJOR_VERSION != TCPIP_CFG_H_SW_MAJOR_VERSION)    \
    || (TCPIP_SW_CFG_DEP_MINOR_VERSION != TCPIP_CFG_H_SW_MINOR_VERSION) \
    || (TCPIP_SW_CFG_DEP_PATCH_VERSION != TCPIP_CFG_H_SW_PATCH_VERSION))
#error "soruce code version is not match configuration"
#endif

#define TCPIP_START_SEC_CODE
#include "TcpIp_MemMap.h"
/***********************************************************************************************************************
 *  LOCAL FUNCTIONS
 ***********************************************************************************************************************/

/***********************************************************************************************************************
 *  GLOBAL FUNCTIONS
 **********************************************************************************************************************/

/***********************************************************************************************************************
 * Service ID[hex]:     0x01
 * Sync/Async:          Synchronous
 * Reentrancy:          Non Reentrant
 * Parameters (in):     ConfigPtr Pointer to the configuration data of the TcpIp module
 * Parameters(inout):   None
 * Parameters (out):    None
 * Return value:        None
 * Description:         This service initializes the TCP/IP Stack.TcpIp_Init may not block the start-up process for an
 *                      indefinite amount of time.
 * Caveats:             The call of this service is mandatory before using the TcpIp instance for further processing.
 ***********************************************************************************************************************/
FUNC(void, TCPIP_CODE)
TcpIp_Init(P2CONST(TcpIp_ConfigType, AUTOMATIC, TCPIP_APPL_CONST) ConfigPtr)
{
#if (STD_ON == TCPIP_DEV_ERROR_DETECT)

    if (NULL_PTR == ConfigPtr)
    {
        TCPIP_DET(TCPIP_SID_INIT, TCPIP_E_PARAM_POINTER);
    }
    else
#endif /* STD_ON == TCPIP_DEV_ERROR_DETECT */
    {

#if (STD_ON == TCPIP_BSDSOCKET_SUPPORT)
        TcpIp_BsdInit(ConfigPtr);
#else /* STD_ON != TCPIP_BSDSOCKET_SUPPORT */
        TcpIp_PbCfgPtr = ConfigPtr;
        lwip_init();
#if (TCPIP_CONTROLLER_NUM > 0u)
        TcpIp_ControllerInit(TcpIp_PbCfgPtr->ctrlNum, TcpIp_PbCfgPtr->CtrlPtr);
#endif /* TCPIP_CONTROLLER_NUM > 0 */
#if (TCPIP_SOCKET_NUM > 0u)
        TcpIp_SocketInit(TCPIP_SOCKET_NUM);
#endif /* TCPIP_SOCKET_NUM > 0u */
        TcpIp_PeriodTimerInit();
#if (STD_ON == TCPIP_TCP_TLS_ENABLED)
        TcpIp_TlsInit(TcpIp_PbCfgPtr->TlsCfgPtr);
#endif /* STD_ON == TCPIP_TCP_TLS_ENABLED */
#if (TCPIP_LOCAL_ADR_NUM > 0u)
        TcpIp_LocalAdrInit(TcpIp_PbCfgPtr->localAdrNum, TcpIp_PbCfgPtr->LocalAdrPtr);
#endif /* TCPIP_LOCAL_ADR_NUM > 0u */

#endif /* STD_ON == TCPIP_BSDSOCKET_SUPPORT */

        TcpIp_InitState = TCPIP_STATE_INIT;
    }
}

#if (STD_ON == TCPIP_VERSION_INFO_API)
/***********************************************************************************************************************
 * Service ID[hex]:     0x02
 * Sync/Async:          Synchronous
 * Reentrancy:          Reentrant
 * Parameters (in):     None
 * Parameters(inout):   None
 * Parameters (out):    versioninfo Pointer to where to store the version information of this module.
 * Return value:        None
 * Description:         Returns the version information.
 ***********************************************************************************************************************/
FUNC(void, TCPIP_CODE)
TcpIp_GetVersionInfo(Std_VersionInfoType* versioninfo)
{
#if (STD_ON == TCPIP_DEV_ERROR_DETECT)

    if (NULL_PTR == versioninfo)
    {
        TCPIP_DET(TCPIP_SID_GETVERSIONINFO, TCPIP_E_PARAM_POINTER);
    }
    else
#endif /* STD_ON == TCPIP_DEV_ERROR_DETECT */
    {
        versioninfo->moduleID = TCPIP_MODULE_ID;
        versioninfo->vendorID = TCPIP_VENDOR_ID;
        versioninfo->sw_major_version = TCPIP_C_SW_MAJOR_VERSION;
        versioninfo->sw_minor_version = TCPIP_C_SW_MINOR_VERSION;
        versioninfo->sw_patch_version = TCPIP_C_SW_PATCH_VERSION;
    }
}
#endif /* STD_ON == TCPIP_VERSION_INFO_API */

/***********************************************************************************************************************
 * Service ID[hex]:     0x04
 * Sync/Async:          Asynchronous
 * Reentrancy:          Reentrant for different SocketIds. Non reentrant for the same SocketId.
 * Parameters (in):     SocketId: Socket handle identifying the local socket resource.
 *                      Abort TRUE: connection will immediately be terminated by sending a RST-Segment and releasing all
 *                      related resources.FALSE: connection will be terminated after performing a regular connection
 *                      termination handshake and releasing all related resources.
 * Parameters(inout):   None
 * Parameters (out):    None
 * Return value:        Std_ReturnType E_OK: The request has been accepted
 * E_NOT_OK:            The request has not been accepted.
 * Description:         By this API service the TCP/IP stack is requested to close the socket and release all related
 *                      resources.
 ***********************************************************************************************************************/
FUNC(Std_ReturnType, TCPIP_CODE)
TcpIp_Close(TcpIp_SocketIdType SocketId, boolean Abort)
{
    Std_ReturnType ret = E_NOT_OK;
#if (STD_ON == TCPIP_DEV_ERROR_DETECT)

    if (TCPIP_STATE_INIT != TcpIp_InitState)
    {
        TCPIP_DET(TCPIP_SID_CLOSE, TCPIP_E_NOTINIT);
    }
    else if (SocketId >= TCPIP_SOCKET_NUM)
    {
        TCPIP_DET(TCPIP_SID_CLOSE, TCPIP_E_INV_ARG);
    }
    else
#endif /* STD_ON == TCPIP_DEV_ERROR_DETECT */
    {
#if (STD_ON == TCPIP_BSDSOCKET_SUPPORT)
        ret = TcpIp_BsdCloseSocketHandle(SocketId, Abort);
#else  /* STD_ON != TCPIP_BSDSOCKET_SUPPORT */
        ret = TcpIp_CloseSocketHandle(SocketId, Abort);
#endif /* STD_ON == TCPIP_BSDSOCKET_SUPPORT */
    }

    return ret;
}

/**********************************************************************************************************************
 * Service ID[hex]:     0x05
 * Sync/Async:          Synchronous
 * Reentrancy:          Reentrant for different SocketIds. Non reentrant for the same SocketId.
 * Parameters (in):     SocketId: Socket identifier of the related local socket resource.
 *                      LocalAddrId: IP address identifier representing the local IP address and EthIf controller to
 *                      bind the socket to.
 * Parameters (inout):  PortPtr Pointer to memory where the local port to which the socket shall be bound is specified.
 *                      In case the parameter is specified as TCPIP_PORT_ANY, the TCP/IP stack shall choose the
 *                      local port automatically from the range 49152 to 65535 and shall update the parameter to the
 *                      chosen value.
 * Parameters (out):    None
 * Return value:        E_OK: The request has been accepted
 *                      E_NOT_OK The request has not been accepted (e.g. address in use)
 * Description:         By this API service the TCP/IP stack is requested to bind a UDP or TCP socket to a local
 *                      resource.
 ***********************************************************************************************************************/
FUNC(Std_ReturnType, TCPIP_CODE)
TcpIp_Bind(TcpIp_SocketIdType SocketId, TcpIp_LocalAddrIdType LocalAddrId, uint16* PortPtr)
{
    Std_ReturnType ret = E_NOT_OK;
#if (STD_ON == TCPIP_DEV_ERROR_DETECT)

    if (TCPIP_STATE_INIT != TcpIp_InitState)
    {
        TCPIP_DET(TCPIP_SID_BIND, TCPIP_E_NOTINIT);
    }
    else if (NULL_PTR == PortPtr)
    {
        TCPIP_DET(TCPIP_SID_BIND, TCPIP_E_PARAM_POINTER);
    }
    else if (
        (SocketId >= TCPIP_SOCKET_NUM)
        || ((LocalAddrId >= TCPIP_LOCAL_ADR_NUM) && (LocalAddrId != TCPIP_LOCALADDRID_ANY)))
    {
        TCPIP_DET(TCPIP_SID_BIND, TCPIP_E_INV_ARG);
    }
    else
#endif /* STD_ON == TCPIP_DEV_ERROR_DETECT */
    {
#if ((TCPIP_LOCAL_ADR_NUM > 0u) && (TCPIP_SOCKET_NUM > 0u))
#if (STD_ON == TCPIP_BSDSOCKET_SUPPORT)
        ret = TcpIp_BsdBind(SocketId, LocalAddrId, PortPtr);
#else  /* STD_ON != TCPIP_BSDSOCKET_SUPPORT */
        uint8 ctrlIdx =
            (LocalAddrId != TCPIP_LOCALADDRID_ANY) ? (TcpIp_PbCfgPtr->LocalAdrPtr[LocalAddrId].ctrlIndex) : 0xFFu;

        ret = TcpIp_InnerBind(ctrlIdx, SocketId, LocalAddrId, PortPtr);
#endif /* STD_ON == TCPIP_BSDSOCKET_SUPPORT */
#endif /* TCPIP_LOCAL_ADR_NUM > 0u && TCPIP_SOCKET_NUM > 0u */
    }

    return ret;
}

#if (STD_ON == TCPIP_TCP_ENABLED)
/***********************************************************************************************************************
 * Service ID[hex]:     0x06
 * Sync/Async:          Asynchronous
 * Reentrancy:          Reentrant for different SocketIds. Non reentrant for the same SocketId.
 * Parameters (in):     SocketId: Socket identifier of the related local socket resource.
 *                      RemoteAddrPtr IP address and port of the remote host to connect to.
 * Parameters(inout):   None
 * Parameters (out):    None
 * Return value:        Std_ReturnType E_OK: The request has been accepted
 *                      E_NOT_OK: The request has not been accepted, e.g. connection is already established or no route
 *                      to destination specified by remoteAddrPtr found.
 * Description:         By this API service the TCP/IP stack is requested to establish a TCP connection to the
 *                      configured peer.
 ***********************************************************************************************************************/
FUNC(Std_ReturnType, TCPIP_CODE)
TcpIp_TcpConnect(
    VAR(TcpIp_SocketIdType, AUTOMATIC) SocketId,
    P2CONST(TcpIp_SockAddrType, AUTOMATIC, TCPIP_APPL_CONST) RemoteAddrPtr)
{
    Std_ReturnType ret = E_NOT_OK;
#if (STD_ON == TCPIP_DEV_ERROR_DETECT)

    if (TCPIP_STATE_INIT != TcpIp_InitState)
    {
        TCPIP_DET(TCPIP_SID_TCPCONNECT, TCPIP_E_NOTINIT);
    }
    else if (NULL_PTR == RemoteAddrPtr)
    {
        TCPIP_DET(TCPIP_SID_TCPCONNECT, TCPIP_E_PARAM_POINTER);
    }
    else if (SocketId >= TCPIP_SOCKET_NUM)
    {
        TCPIP_DET(TCPIP_SID_TCPCONNECT, TCPIP_E_INV_ARG);
    }
    else
#endif /* STD_ON == TCPIP_DEV_ERROR_DETECT */
    {
#if (STD_ON == TCPIP_BSDSOCKET_SUPPORT)
        ret = TcpIp_BsdTcpConnect(SocketId, RemoteAddrPtr);
#else  /* STD_ON != TCPIP_BSDSOCKET_SUPPORT */
        ret = TcpIp_InnerTcpConnect(SocketId, RemoteAddrPtr);
#endif /* STD_ON == TCPIP_BSDSOCKET_SUPPORT */
    }

    return ret;
}

/***********************************************************************************************************************
 * Service ID[hex]:     0x07
 * Sync/Async:          Asynchronous
 * Reentrancy:          Reentrant for different SocketIds. Non reentrant for the same SocketId.
 * Parameters (in):     SocketId: Socket identifier of the related local socket resource.
 *                      MaxChannels: Maximum number of new parallel connections established on this listen connection.
 * Parameters(inout):   None
 * Parameters (out):    None
 * Return value:        Std_ReturnType E_OK: The request has been accepted
 *                      E_NOT_OK: The request has not been accepted, the socket is not configured to be a server socket.
 * Description:         By this API service the TCP/IP stack is requested to listen on the TCP socket specified
 *                      by the socket identifier.
 ***********************************************************************************************************************/
FUNC(Std_ReturnType, TCPIP_CODE)
TcpIp_TcpListen(TcpIp_SocketIdType SocketId, uint16 MaxChannels)
{
    Std_ReturnType ret = E_NOT_OK;
#if (STD_ON == TCPIP_DEV_ERROR_DETECT)

    if (TCPIP_STATE_INIT != TcpIp_InitState)
    {
        TCPIP_DET(TCPIP_SID_TCPLISTEN, TCPIP_E_NOTINIT);
    }
    else if (SocketId >= TCPIP_SOCKET_NUM)
    {
        TCPIP_DET(TCPIP_SID_TCPLISTEN, TCPIP_E_INV_ARG);
    }
    else
#endif /* STD_ON == TCPIP_DEV_ERROR_DETECT */
    {
#if (STD_ON == TCPIP_BSDSOCKET_SUPPORT)
        ret = TcpIp_BsdTcpListen(SocketId, MaxChannels);
#else  /* STD_ON != TCPIP_BSDSOCKET_SUPPORT */
        uint8 maxCh = (MaxChannels > 0xffu) ? 0xffu : (uint8)MaxChannels;
        ret = TcpIp_InnerTcpListen(SocketId, maxCh);
#endif /* STD_ON == TCPIP_BSDSOCKET_SUPPORT */
    }

    return ret;
}

/***********************************************************************************************************************
 * Service ID[hex]:     0x08
 * Sync/Async:          Asynchronous
 * Reentrancy:          Reentrant for different SocketIds. Non reentrant for the same SocketId.
 * Parameters (in):     SocketId Socket identifier of the related local socket resource
 *                      Length Number of bytes finally consumed by the upper layer.
 * Parameters(inout):   None
 * Parameters (out):    None
 * Return value:        Std_ReturnType E_OK: The request has been accepted
 *                      E_NOT_OK: The request has not been accepted
 * Description:         By this API service the reception of socket data is confirmed to the TCP/IP stack.
 ***********************************************************************************************************************/
FUNC(Std_ReturnType, TCPIP_CODE)
TcpIp_TcpReceived(TcpIp_SocketIdType SocketId, uint32 Length)
{
    Std_ReturnType ret = E_NOT_OK;
#if (STD_ON == TCPIP_DEV_ERROR_DETECT)

    if (TCPIP_STATE_INIT != TcpIp_InitState)
    {
        TCPIP_DET(TCPIP_SID_TCPRECEIVED, TCPIP_E_NOTINIT);
    }
    else if (SocketId >= TCPIP_SOCKET_NUM)
    {
        TCPIP_DET(TCPIP_SID_TCPRECEIVED, TCPIP_E_INV_ARG);
    }
    else
#endif /* STD_ON == TCPIP_DEV_ERROR_DETECT */
    {
#if (STD_ON == TCPIP_BSDSOCKET_SUPPORT)

#else  /* STD_ON != TCPIP_BSDSOCKET_SUPPORT */
        uint16 revcLen = (Length > 0xffffu) ? 0xffffu : (uint16)Length;
        ret = TcpIp_InnerTcpReceived(SocketId, revcLen);
#endif /* STD_ON == TCPIP_BSDSOCKET_SUPPORT */
    }

    return ret;
}
#endif /* STD_ON == TCPIP_TCP_ENABLED */

/***********************************************************************************************************************
 * Service ID[hex]:     0x09
 * Sync/Async:          Asynchronous
 * Reentrancy:          Non Reentrant
 * Parameters (in):     CtrlIdx: EthIf controller index to identify the communication network where the TcpIp state is
 *                      requested.
 *                      State: Requested TcpIp state.
 * Parameters(inout):   None
 * Parameters (out):    None
 * Return value:        Std_ReturnType E_OK: Service accepted
 *                      E_NOT_OK: Service denied
 * Description:         By this API service the TCP/IP stack is requested to change the TcpIp state of the communication
 *                      network identified by EthIf controller index.
 ***********************************************************************************************************************/
FUNC(Std_ReturnType, TCPIP_CODE)
TcpIp_RequestComMode(uint8 CtrlIdx, TcpIp_StateType State)
{
    Std_ReturnType ret = E_NOT_OK;
#if (STD_ON == TCPIP_DEV_ERROR_DETECT)

    if (TCPIP_STATE_INIT != TcpIp_InitState)
    {
        TCPIP_DET(TCPIP_SID_REQUESTCOMMODE, TCPIP_E_NOTINIT);
    }
    else if ((TCPIP_STATE_STARTUP == State) || (TCPIP_STATE_SHUTDOWN == State))
    {
        TCPIP_DET(TCPIP_SID_REQUESTCOMMODE, TCPIP_E_INV_ARG);
    }
#if (TCPIP_CONTROLLER_NUM > 0u)
    else if (
        (CtrlIdx > TcpIp_PbCfgPtr->ethIfCtrlMax)
#if (TCPIP_CONTROLLER_NUM > 1u)
        || (TcpIp_PbCfgPtr->EthIfCtrlRefMapping[CtrlIdx] >= TCPIP_CONTROLLER_NUM)
#endif /* TCPIP_CONTROLLER_NUM > 1u */
    )
    {
        TCPIP_DET(TCPIP_SID_GETREMOTEPHYSADDR, TCPIP_E_INV_ARG);
    }
#endif /* TCPIP_CONTROLLER_NUM > 0 */
    else
#endif /* STD_ON == TCPIP_DEV_ERROR_DETECT */
    {
#if (TCPIP_CONTROLLER_NUM > 0u)
#if (STD_ON == TCPIP_BSDSOCKET_SUPPORT)
#if (TCPIP_CONTROLLER_NUM == 1u)
        ret = TcpIp_BsdRequestComMode(0u, State);
#else
        ret = TcpIp_BsdRequestComMode(TcpIp_PbCfgPtr->EthIfCtrlRefMapping[CtrlIdx], State);
#endif /* TCPIP_CONTROLLER_NUM == 1u */
#else  /* STD_ON != TCPIP_BSDSOCKET_SUPPORT */
#if (TCPIP_CONTROLLER_NUM == 1u)
        ret = TcpIp_InnerRequestComMode(0u, State);
#else
        ret = TcpIp_InnerRequestComMode(TcpIp_PbCfgPtr->EthIfCtrlRefMapping[CtrlIdx], State);
#endif /* TCPIP_CONTROLLER_NUM == 1u */
#endif /* STD_ON == TCPIP_BSDSOCKET_SUPPORT */
#endif /* TCPIP_CONTROLLER_NUM > 0 */
    }

    return ret;
}

/***********************************************************************************************************************
 * Service ID[hex]:     0x0A
 * Sync/Async:          Asynchronous
 * Reentrancy:          Non Reentrant
 * Parameters (in):     LocalAddrId: IP address index specifying the IP address for which an assignment shall be
 *                      initiated.
 *                      Type: Type of IP address assignment which shall be initiated
 *                      LocalIpAddrPtr: Pointer to structure containing the IP address which shall be assigned to the
 *                      EthIf controller indirectly specified via LocalAddrId.
 *                      Netmask: Network mask of IPv4 address or address prefix of IPv6 address in CIDR Notation.
 *                      DefaultRouterPtr: Pointer to structure containing the IP address of the default router
 *                      (gateway) which shall be assigned.
 * Parameters(inout):   None
 * Parameters (out):    None
 * Return value:        Std_ReturnType E_OK: The request has been accepted
 *                      E_NOT_OK: The request has not been accepted
 * Description:         By this API service the local IP address assignment for the IP address specified by LocalAddrId
 *                      shall be initiated.
 ***********************************************************************************************************************/
FUNC(Std_ReturnType, TCPIP_CODE)
TcpIp_RequestIpAddrAssignment(
    VAR(TcpIp_LocalAddrIdType, AUTOMATIC) LocalAddrId,
    VAR(TcpIp_IpAddrAssignmentType, AUTOMATIC) Type,
    P2CONST(TcpIp_SockAddrType, AUTOMATIC, TCPIP_APPL_CONST) LocalIpAddrPtr,
    VAR(uint8, AUTOMATIC) Netmask,
    P2CONST(TcpIp_SockAddrType, AUTOMATIC, TCPIP_APPL_CONST) DefaultRouterPtr)
{
    Std_ReturnType ret = E_NOT_OK;
#if (STD_ON == TCPIP_DEV_ERROR_DETECT)

    if (TCPIP_STATE_INIT != TcpIp_InitState)
    {
        TCPIP_DET(TCPIP_SID_REQUESTIPADDRASSIGNMENT, TCPIP_E_NOTINIT);
    }
    else if (TCPIP_LOCAL_ADR_NUM <= LocalAddrId)
    {
        TCPIP_DET(TCPIP_SID_REQUESTIPADDRASSIGNMENT, TCPIP_E_NOTINIT);
    }
    else
#endif /* STD_ON == TCPIP_DEV_ERROR_DETECT */
    {
#if (TCPIP_LOCAL_ADR_NUM > 0)
#if (STD_ON == TCPIP_BSDSOCKET_SUPPORT)
        ret = TcpIp_BsdRequestIpAddrAssignment(LocalAddrId, Type, LocalIpAddrPtr, Netmask, DefaultRouterPtr);
#else                                            /* STD_ON != TCPIP_BSDSOCKET_SUPPORT */

        const TcpIp_LocalAddrType* localAdrCfgPtr = &TcpIp_PbCfgPtr->LocalAdrPtr[LocalAddrId];
#if (TCPIP_LOCALADDR_MUILT_ASSIGNMENT == STD_ON) /* PRQA S 3332 */
        uint32 addrAssignmentNum = TcpIp_PbCfgPtr->LocalAdrPtr[LocalAddrId].AddrAssignmentNum;

        for (uintx index = 0u; index < addrAssignmentNum; index++)
#else                                            /* TCPIP_LOCALADDR_MUILT_ASSIGNMENT == STD_ON */
        uintx index = 0u;

#endif /* TCPIP_LOCALADDR_MUILT_ASSIGNMENT == STD_ON */
        {
            const TcpIp_AddrAssignmentType* addrCfg = &(localAdrCfgPtr->AddrAssignmentCfgPtr[index]);

            if (((Type == addrCfg->AssignmentMethod) || (TCPIP_IPADDR_ASSIGNMENT_ALL == Type))
                && (TCPIP_MANUAL == addrCfg->AssignmentTrigger)
                && (TCPIP_STATE_OFFLINE
                    != TcpIp_GetControlState(localAdrCfgPtr->ctrlIndex))) /* PRQA S 3415 */ /* MISRA Rule 13.5 */
            {
                switch (addrCfg->AssignmentMethod)
                {
                case TCPIP_IPADDR_ASSIGNMENT_STATIC:
                    if (NULL_PTR != localAdrCfgPtr->StaticIpAddressCfgPtr)
                    {
                        /* configure data as local address var */
                        ret =
                            TcpIp_SetLocalAdrIpVar(LocalAddrId, localAdrCfgPtr, localAdrCfgPtr->StaticIpAddressCfgPtr);
                    }
                    else if (NULL_PTR != LocalIpAddrPtr)
                    {
#if (TCPIP_SC1 == TCPIP_SCALABILITY_CLASS)
                        uint32 netMask[1] = {0};
#else
                        uint32 netMask[4] = {0};
#endif /* TCPIP_SC1 == TCPIP_SCALABILITY_CLASS */
                        TcpIp_NetMaskExtToInner(Netmask, localAdrCfgPtr->DomainType, netMask);
                        /* function input parameter as local address var */
                        TcpIp_StaticIpAddressConfigType ipAdr = {0};

                        if (NULL_PTR != DefaultRouterPtr)
                        {
                            ipAdr.DefaultRouterPtr = DefaultRouterPtr->addr;
                        }

                        ipAdr.NetmaskPtr = netMask;
                        ipAdr.StaticIpAddressPtr = LocalIpAddrPtr->addr;
                        ret = TcpIp_SetLocalAdrIpVar(LocalAddrId, localAdrCfgPtr, &ipAdr);
                    }
                    else
                    {
                        TCPIP_CHECK_OUTPUT("input parameters is error\n");
                    }

                    break;

                case TCPIP_IPADDR_ASSIGNMENT_DHCP:
#if (STD_ON == TCPIP_DHCP_CLIENT_ENABLED)
                    ret = TcpIp_StartDhcp(localAdrCfgPtr->ctrlIndex);
#endif /* STD_ON == TCPIP_DHCP_CLIENT_ENABLED */
                    break;

                case TCPIP_IPADDR_ASSIGNMENT_LINKLOCAL_DOIP:
                case TCPIP_IPADDR_ASSIGNMENT_LINKLOCAL:
#if (STD_ON == TCPIP_AUTOIP_ENABLED)
                    ret = TcpIp_StartAutoIp(localAdrCfgPtr->ctrlIndex);
#endif /* STD_ON == TCPIP_AUTOIP_ENABLED */
                    break;

                default: /* PRQA S 2016 */ /* MISRA Rule 16.4 */
                    break;
                }

#if (TCPIP_LOCALADDR_MUILT_ASSIGNMENT == STD_ON) /* PRQA S 3332 */
                /* find type is accordance shall be quit pool */
                break;
#endif                                           /* TCPIP_LOCALADDR_MUILT_ASSIGNMENT == STD_ON */
            }
        }
#endif                                           /* STD_ON == TCPIP_BSDSOCKET_SUPPORT */

#endif /* TCPIP_LOCAL_ADR_NUM > 0 */
    }

    return ret;
}

/***********************************************************************************************************************
 * Service ID[hex]:     0x0B
 * Sync/Async:          Asynchronous
 * Reentrancy:          Non Reentrant
 * Parameters (in):     LocalAddrId IP address index specifying the IP address for which an assignment shall be
 *                      released.
 * Parameters(inout):   None
 * Parameters (out):    None
 * Return value:        Std_ReturnType E_OK: The request has been accepted
 *                      E_NOT_OK: The request has not been accepted
 * Description:         By this API service the local IP address assignment for the IP address specified by LocalAddrId
 *                      shall be released.
 ***********************************************************************************************************************/
FUNC(Std_ReturnType, TCPIP_CODE)
TcpIp_ReleaseIpAddrAssignment(VAR(TcpIp_LocalAddrIdType, AUTOMATIC) LocalAddrId)
{
    Std_ReturnType ret = E_NOT_OK;
#if (STD_ON == TCPIP_DEV_ERROR_DETECT)

    if (TCPIP_STATE_INIT != TcpIp_InitState)
    {
        TCPIP_DET(TCPIP_SID_RELEASEIPADDRASSIGNMENT, TCPIP_E_NOTINIT);
    }
    else if (TCPIP_LOCAL_ADR_NUM <= LocalAddrId)
    {
        TCPIP_DET(TCPIP_SID_RELEASEIPADDRASSIGNMENT, TCPIP_E_INV_ARG);
    }
    else
#endif /* STD_ON == TCPIP_DEV_ERROR_DETECT */
    {
#if (TCPIP_LOCAL_ADR_NUM > 0)
#if (STD_ON == TCPIP_BSDSOCKET_SUPPORT)
        ret = TcpIp_BsdReleaseIpAddrAssignment(LocalAddrId);
#else                                            /* STD_ON != TCPIP_BSDSOCKET_SUPPORT */

        const TcpIp_LocalAddrType* localAdrCfgPtr = &TcpIp_PbCfgPtr->LocalAdrPtr[LocalAddrId];
#if (TCPIP_LOCALADDR_MUILT_ASSIGNMENT == STD_ON) /* PRQA S 3332 */
        uint32 addrAssignmentNum = TcpIp_PbCfgPtr->LocalAdrPtr[LocalAddrId].AddrAssignmentNum;

        for (uint32 index = 0; index < addrAssignmentNum; index++)
#else                                            /* TCPIP_LOCALADDR_MUILT_ASSIGNMENT != STD_ON */
        uint32 index = 0;

#endif /* TCPIP_LOCALADDR_MUILT_ASSIGNMENT == STD_ON */
        {
            const TcpIp_AddrAssignmentType* addrCfg = &(localAdrCfgPtr->AddrAssignmentCfgPtr[index]);

            /* [SWS_TCPIP_00199] release TCPIP_AUTOMATIC shall be reject and return E_NOT_OK */
            if ((TCPIP_MANUAL == addrCfg->AssignmentTrigger)
                && (TCPIP_STATE_OFFLINE
                    != TcpIp_GetControlState(localAdrCfgPtr->ctrlIndex))) /* PRQA S 3415 */ /* MISRA Rule 13.5 */
            {
                ret = TcpIp_ClearLocalAdrIpVar(LocalAddrId, localAdrCfgPtr->ctrlIndex, addrCfg->AssignmentMethod);
            }

#if (TCPIP_LOCALADDR_MUILT_ASSIGNMENT == STD_ON) /* PRQA S 3332 */

            if (E_OK != ret)
            {
                break;
            }

#endif /* TCPIP_LOCALADDR_MUILT_ASSIGNMENT == STD_ON */
        }
#endif /* STD_ON == TCPIP_BSDSOCKET_SUPPORT */

#endif /* TCPIP_LOCAL_ADR_NUM > 0 */
    }
    return ret;
}

#if ((STD_ON == TCPIP_DHCP_CLIENT_ENABLED) && (STD_ON == TCPIP_RESET_IP_ASSIGNMENT_API))
/***********************************************************************************************************************
 * Service ID[hex]:     0x1b
 * Sync/Async:          Synchronous /Asynchronous
 * Reentrancy:          Non Reentrant
 * Parameters (in):     None
 * Parameters(inout):   None
 * Parameters (out):    None
 * Return value:        Std_ReturnType E_OK: success
 *                      E_NOT_OK: switch port could not be initialized
 * Description:         Resets all learned IP-addresses to invalid values.
 ***********************************************************************************************************************/
FUNC(Std_ReturnType, TCPIP_CODE)
TcpIp_ResetIpAssignment(void)
{
    Std_ReturnType ret = E_NOT_OK;
#if (STD_ON == TCPIP_DEV_ERROR_DETECT)

    if (TCPIP_STATE_INIT != TcpIp_InitState)
    {
        TCPIP_DET(TCPIP_SID_RESETIPASSIGNMENT, TCPIP_E_NOTINIT);
    }
    else
#endif /* STD_ON == TCPIP_DEV_ERROR_DETECT */
    {
    }

    return ret;
}
#endif /* STD_ON == TCPIP_DHCP_CLIENT_ENABLED && STD_ON == TCPIP_RESET_IP_ASSIGNMENT_API */
#if (STD_ON == TCPIP_ICMP_ENABLED)
#if ((TCPIP_SC1 == TCPIP_SCALABILITY_CLASS) || (TCPIP_SC3 == TCPIP_SCALABILITY_CLASS))
/***********************************************************************************************************************
 * Service ID[hex]:     0x0C
 * Sync/Async:          Synchronous
 * Reentrancy:          Non Reentrant
 * Parameters (in):     LocalIpAddrId: IP address identifier representing the local IP address and EthIf controller
 *                      which shall be used for transmission of the ICMP message.
 *                      RemoteAddrPtr: pointer to struct representing the remote address Ttl Time to live value to be
 *                      used for the ICMP message. If 0 is specified the default value shall be used.
 *                      Type: type field value to be used in the ICMP message
 *                      Code: code field value to be used in the ICMP message
 *                      DataLength: length of ICMP message
 *                      DataPtr: Pointer to data which shall be sent as ICMP message data
 * Parameters(inout):   None
 * Parameters (out):    None
 * Return value:        Std_ReturnType Result of operation
 *                      E_OK: The ICMP message has been sent successfully
 *                      E_NOT_OK: The ICMP message was not sent.
 * Description:         By this API service the TCP/IP stack sends an ICMP message according to the specified
 *                      parameters.
 ***********************************************************************************************************************/
FUNC(Std_ReturnType, TCPIP_CODE)
TcpIp_IcmpTransmit(
    VAR(TcpIp_LocalAddrIdType, AUTOMATIC) LocalIpAddrId,
    P2CONST(TcpIp_SockAddrType, AUTOMATIC, TCPIP_APPL_CONST) RemoteAddrPtr,
    VAR(uint8, AUTOMATIC) Ttl,
    VAR(uint8, AUTOMATIC) Type,
    VAR(uint8, AUTOMATIC) Code,
    VAR(uint16, AUTOMATIC) DataLength,
    P2CONST(uint8, AUTOMATIC, TCPIP_APPL_CONST) DataPtr)
{
    Std_ReturnType ret = E_NOT_OK;
#if (STD_ON == TCPIP_DEV_ERROR_DETECT)

    if (TCPIP_STATE_INIT != TcpIp_InitState)
    {
        TCPIP_DET(TCPIP_SID_ICMPTRANSMIT, TCPIP_E_NOTINIT);
    }
    else if ((TCPIP_LOCAL_ADR_NUM <= LocalIpAddrId) || (0u == DataLength))
    {
        TCPIP_DET(TCPIP_SID_ICMPTRANSMIT, TCPIP_E_INV_ARG);
    }
    else if (NULL_PTR == DataPtr)
    {
        TCPIP_DET(TCPIP_SID_ICMPTRANSMIT, TCPIP_E_PARAM_POINTER);
    }
    else
#endif /* STD_ON == TCPIP_DEV_ERROR_DETECT */
    {
#if (TCPIP_CONTROLLER_NUM > 0u)
#if (STD_ON != TCPIP_BSDSOCKET_SUPPORT)

        TcpIp_IcmpTransDataType icmpPara = {0};
        icmpPara.ttl = Ttl;
        icmpPara.type = Type;
        icmpPara.code = Code;
        icmpPara.dataPtr = DataPtr;
        icmpPara.dataLength = DataLength;
        ret = TcpIp_InnerIcmpTransmit(
            LocalIpAddrId,
            TcpIp_PbCfgPtr->LocalAdrPtr[LocalIpAddrId].ctrlIndex,
            RemoteAddrPtr,
            &icmpPara);
#endif /* STD_ON != TCPIP_BSDSOCKET_SUPPORT */
#endif /* TCPIP_CONTROLLER_NUM > 0u */
    }

    return ret;
}
#endif /* TCPIP_SC1 == TCPIP_SCALABILITY_CLASS || TCPIP_SC3 == TCPIP_SCALABILITY_CLASS */
#if ((TCPIP_SC2 == TCPIP_SCALABILITY_CLASS) || (TCPIP_SC3 == TCPIP_SCALABILITY_CLASS))
/***********************************************************************************************************************
 * Service ID[hex]:     0x18
 * Sync/Async:          Synchronous
 * Reentrancy:          Non Reentrant
 * Parameters (in):     LocalIpAddrId: IP address identifier representing the local IP address and EthIf controller
 *                      which shall be used for transmission of the ICMPv6 message.
 *                      RemoteAddrPtr: pointer to struct representing the remote address HopLimit Hop Limit value to
 *                      be used for the ICMPv6 message. If 0 is specified the default value shall be used.
 *                      Type: type field value to be used in the ICMPv6 message.
 *                      Code: code field value to be used in the ICMPv6 message
 *                      DataLength: length of ICMPv6 message
 *                      DataPtr: Pointer to data which shall be sent as ICMPv6 message data
 * Parameters(inout):   None
 * Parameters (out):    None
 * Return value:        Std_ReturnType Result of operation
 *                      E_OK: The ICMPv6 message has been sent successfully
 *                      E_NOT_OK: The ICMPv6 message was not sent.
 * Description:         By this API service the TCP/IP stack sends an ICMPv6 message according to the
 *                      specified parameters.
 ***********************************************************************************************************************/
FUNC(Std_ReturnType, TCPIP_CODE)
TcpIp_IcmpV6Transmit(
    VAR(TcpIp_LocalAddrIdType, AUTOMATIC) LocalIpAddrId,
    P2CONST(TcpIp_SockAddrType, AUTOMATIC, TCPIP_APPL_CONST) RemoteAddrPtr,
    VAR(uint8, AUTOMATIC) HopLimit,
    VAR(uint8, AUTOMATIC) Type,
    VAR(uint8, AUTOMATIC) Code,
    VAR(uint16, AUTOMATIC) DataLength,
    P2CONST(uint8, AUTOMATIC, TCPIP_APPL_CONST) DataPtr)
{
    Std_ReturnType ret = E_NOT_OK;
#if (STD_ON == TCPIP_DEV_ERROR_DETECT)

    if (TCPIP_STATE_INIT != TcpIp_InitState)
    {
        TCPIP_DET(TCPIP_SID_ICMPV6TRANSMIT, TCPIP_E_NOTINIT);
    }
    else
#endif /* STD_ON == TCPIP_DEV_ERROR_DETECT */
    {
    }

    return ret;
}
#endif /* TCPIP_SC2 == TCPIP_SCALABILITY_CLASS || TCPIP_SC3 == TCPIP_SCALABILITY_CLASS */
#endif /* STD_ON == TCPIP_ICMP_ENABLED */
#if ((TCPIP_SC1 == TCPIP_SCALABILITY_CLASS) || (TCPIP_SC3 == TCPIP_SCALABILITY_CLASS))
/***********************************************************************************************************************
 * Service ID[hex]:     0x0D
 * Sync/Async:          Synchronous
 * Reentrancy:          Non Reentrant
 * Parameters (in):     LocalIpAddrId IP address identifier representing the local IP address and EthIf controller for
 *                      which the DHCP option shall be read.
 *                      Option: DHCP option according to IEFT RfC 2132, e.g. hostname
 *                      DataPtr: Pointer to memory containing DHCP option data
 * Parameters(inout):   DataLength: As input parameter, contains the length of the provided data buffer. Will be
 *                      overwritten with the length of the actual data.
 * Parameters (out):    None
 * Return value:        Std_ReturnType Result of operation
 *                      E_OK requested data retrieved successfully.
 *                      E_NOT_OK requested data could not be retrieved.
 * Description:         By this API service the TCP/IP stack retrieves DHCP option data identified by parameter option
 *                      for already received DHCP options.
 ***********************************************************************************************************************/
/* PRQA S 3673 ++ */ /* MISRA Rule 8.13 */
FUNC(Std_ReturnType, TCPIP_CODE)
TcpIp_DhcpReadOption(TcpIp_LocalAddrIdType LocalIpAddrId, uint8 Option, uint8* DataLength, uint8* DataPtr)
/* PRQA S 3673 -- */ /* MISRA Rule 8.13 */
{
    TCPIP_UNUSED_ARG(LocalIpAddrId);
    TCPIP_UNUSED_ARG(Option);
    TCPIP_UNUSED_ARG(DataLength);
    TCPIP_UNUSED_ARG(DataPtr);
    Std_ReturnType ret = E_NOT_OK;
#if (STD_ON == TCPIP_DEV_ERROR_DETECT)

    if (TCPIP_STATE_INIT != TcpIp_InitState)
    {
        TCPIP_DET(TCPIP_SID_DHCPREADOPTION, TCPIP_E_NOTINIT);
    }
    else if (TCPIP_LOCAL_ADR_NUM <= LocalIpAddrId)
    {
        TCPIP_DET(TCPIP_SID_DHCPREADOPTION, TCPIP_E_INV_ARG);
    }
    else if ((NULL_PTR == DataLength) || (NULL_PTR == DataPtr))
    {
        TCPIP_DET(TCPIP_SID_DHCPREADOPTION, TCPIP_E_PARAM_POINTER);
    }
    /* check if the parameter LocalIpAddrId is valid
       check if the parameter Option is valid
       check if the parameter DataLength is valid
       TCPIP_E_INV_ARG*/
    else
#endif /* STD_ON == TCPIP_DEV_ERROR_DETECT */
    {
    }

    return ret;
}
#endif /* TCPIP_SC1 == TCPIP_SCALABILITY_CLASS || TCPIP_SC3 == TCPIP_SCALABILITY_CLASS */
#if ((TCPIP_SC2 == TCPIP_SCALABILITY_CLASS) || (TCPIP_SC3 == TCPIP_SCALABILITY_CLASS))
/***********************************************************************************************************************
 * Service ID[hex]:     0x0D
 * Sync/Async:          Synchronous
 * Reentrancy:          Non Reentrant
 * Parameters (in):     LocalIpAddrId IP address identifier representing the local IP address and EthIf controller for
 *                      which the DHCPv6 option shall be read.
 *                      Option: DHCP option according to IEFT RfC 3315, e.g. hostname
 *                      DataPtr: Pointer to memory containing DHCP option data
 * Parameters(inout):   DataLength: As input parameter, contains the length of the provided data buffer. Will be
 *                      overwritten with the length of the actual data.
 * Parameters (out):    None
 * Return value:        Std_ReturnType Result of operation
 *                      E_OK requested data retrieved successfully.
 *                      E_NOT_OK requested data could not be retrieved.
 * Description:         By this API service the TCP/IP stack retrieves DHCP option data identified by parameter option
 *                      for already received DHCP options.
 ***********************************************************************************************************************/
FUNC(Std_ReturnType, TCPIP_CODE)
TcpIp_DhcpV6ReadOption(
    VAR(TcpIp_LocalAddrIdType, AUTOMATIC) LocalIpAddrId,
    VAR(uint8, AUTOMATIC) Option,
    P2VAR(uint8, AUTOMATIC, TCPIP_APPL_DATA) DataLength,
    P2VAR(uint8, AUTOMATIC, TCPIP_APPL_DATA) DataPtr)
{
    Std_ReturnType ret = E_NOT_OK;
#if (STD_ON == TCPIP_DEV_ERROR_DETECT)

    if (TCPIP_STATE_INIT != TcpIp_InitState)
    {
        TCPIP_DET(TCPIP_SID_DHCPV6READOPTION, TCPIP_E_NOTINIT);
    }
    else if (TCPIP_LOCAL_ADR_NUM <= LocalIpAddrId)
    {
        TCPIP_DET(TCPIP_SID_DHCPV6READOPTION, TCPIP_E_INV_ARG);
    }
    else if ((NULL_PTR == DataLength) || (NULL_PTR == DataPtr))
    {
        TCPIP_DET(TCPIP_SID_DHCPV6READOPTION, TCPIP_E_PARAM_POINTER);
    }
    else
#endif /* STD_ON == TCPIP_DEV_ERROR_DETECT */
    {
    }

    return ret;
}
#endif /* TCPIP_SC2 == TCPIP_SCALABILITY_CLASS || TCPIP_SC3 == TCPIP_SCALABILITY_CLASS */
#if ((TCPIP_SC1 == TCPIP_SCALABILITY_CLASS) || (TCPIP_SC3 == TCPIP_SCALABILITY_CLASS))
/***********************************************************************************************************************
 * Service ID[hex]:     0x0E
 * Sync/Async:          Synchronous
 * Reentrancy:          Non Reentrant
 * Parameters (in):     LocalIpAddrId: IP address identifier representing the local IP address and EthIf controller for
 *                      which the DHCP option shall be written.
 *                      Option: DHCP option according to IEFT RfC 2132, e.g. hostname
 *                      DataLength: length of DHCP option data
 *                      DataPtr: Pointer to memory containing DHCP option data
 * Parameters(inout):   None
 * Parameters (out):    None
 * Return value:        Std_ReturnType: Result of operation
 *                      E_OK no error occured.
 *                      E_NOT_OK DHCP option data could not be written.
 * Description:         By this API service the TCP/IP stack writes the DHCP option data identified by parameter option.
 ***********************************************************************************************************************/
FUNC(Std_ReturnType, TCPIP_CODE)
TcpIp_DhcpWriteOption(
    VAR(TcpIp_LocalAddrIdType, AUTOMATIC) LocalIpAddrId,
    VAR(uint8, AUTOMATIC) Option,
    VAR(uint8, AUTOMATIC) DataLength,
    P2CONST(uint8, AUTOMATIC, TCPIP_APPL_CONST) DataPtr)
{
    TCPIP_UNUSED_ARG(LocalIpAddrId);
    TCPIP_UNUSED_ARG(Option);
    TCPIP_UNUSED_ARG(DataLength);
    TCPIP_UNUSED_ARG(DataPtr);
    Std_ReturnType ret = E_NOT_OK;
#if (STD_ON == TCPIP_DEV_ERROR_DETECT)

    if (TCPIP_STATE_INIT != TcpIp_InitState)
    {
        TCPIP_DET(TCPIP_SID_DHCPWRITEOPTION, TCPIP_E_NOTINIT);
    }
    else if (TCPIP_LOCAL_ADR_NUM <= LocalIpAddrId)
    {
        TCPIP_DET(TCPIP_SID_DHCPWRITEOPTION, TCPIP_E_INV_ARG);
    }
    else
#endif /* STD_ON == TCPIP_DEV_ERROR_DETECT */
    {
    }

    return ret;
}
#endif /* TCPIP_SC1 == TCPIP_SCALABILITY_CLASS || TCPIP_SC3 == TCPIP_SCALABILITY_CLASS */
#if ((TCPIP_SC2 == TCPIP_SCALABILITY_CLASS) || (TCPIP_SC3 == TCPIP_SCALABILITY_CLASS))
/***********************************************************************************************************************
 * Service ID[hex]:     0x0E
 * Sync/Async:          Synchronous
 * Reentrancy:          Non Reentrant
 * Parameters (in):     LocalIpAddrId: LocalIpAddrId IP address identifier representing the local IP address and EthIf
 *                      controller for which the DHCPv6 option shall be written.
 *                      Option:DHCP option according to IEFT RfC 3315, e.g. hostname
 *                      DataLength: length of DHCP option data
 *                      DataPtr: Pointer to memory containing DHCP option data
 * Parameters(inout):   None
 * Parameters (out):    None
 * Return value:        Std_ReturnType: Result of operation
 *                      E_OK no error occured.
 *                      E_NOT_OK DHCP option data could not be written.
 * Description:         By this API service the TCP/IP stack writes the DHCP option data identified by parameter option.
 ***********************************************************************************************************************/
FUNC(Std_ReturnType, TCPIP_CODE)
TcpIp_DhcpV6WriteOption(
    VAR(TcpIp_LocalAddrIdType, AUTOMATIC) LocalIpAddrId,
    VAR(uint8, AUTOMATIC) Option,
    VAR(uint8, AUTOMATIC) DataLength,
    P2CONST(uint8, AUTOMATIC, TCPIP_APPL_CONST) DataPtr)
{
    Std_ReturnType ret = E_NOT_OK;
#if (STD_ON == TCPIP_DEV_ERROR_DETECT)

    if (TCPIP_STATE_INIT != TcpIp_InitState)
    {
        TCPIP_DET(TCPIP_SID_DHCPV6WRITEOPTION, TCPIP_E_NOTINIT);
    }
    else if (TCPIP_LOCAL_ADR_NUM <= LocalIpAddrId)
    {
        TCPIP_DET(TCPIP_SID_DHCPV6WRITEOPTION, TCPIP_E_INV_ARG);
    }
    else
#endif /* STD_ON == TCPIP_DEV_ERROR_DETECT */
    {
    }
}
#endif /* TCPIP_SC2 == TCPIP_SCALABILITY_CLASS || TCPIP_SC3 == TCPIP_SCALABILITY_CLASS */

/***********************************************************************************************************************
* Service ID[hex]:      0x0F
* Sync/Async:           Synchronous
* Reentrancy:           Reentrant for different SocketIds. Non reentrant for the same SocketId.
* Parameters (in):      SocketId: Socket identifier of the related local socket resource.
*                       ParameterId: Identifier of the parameter to be changed
*                       ParameterValue: Pointer to memory containing the new parameter value
* Parameters(inout):    None
* Parameters (out):     None
* Return value:         Std_ReturnType E_OK: The parameter has been changed successfully.
*                       E_NOT_OK: The parameter could not be changed.
* Description:          By this API service the TCP/IP stack is requested to change a parameter of a socket.E.g. the
                        Nagle algorithm may be controlled by this API
***********************************************************************************************************************/
FUNC(Std_ReturnType, TCPIP_CODE)
TcpIp_ChangeParameter(
    VAR(TcpIp_SocketIdType, AUTOMATIC) SocketId,
    VAR(TcpIp_ParamIdType, AUTOMATIC) ParameterId,
    P2CONST(void, AUTOMATIC, TCPIP_APPL_CONST) ParameterValue)
{
    Std_ReturnType ret = E_OK;
#if (STD_ON == TCPIP_DEV_ERROR_DETECT)

    if (TCPIP_STATE_INIT != TcpIp_InitState)
    {
        TCPIP_DET(TCPIP_SID_CHANGEPARAMETER, TCPIP_E_NOTINIT);
    }
    else if (SocketId >= TCPIP_SOCKET_NUM)
    {
        TCPIP_DET(TCPIP_SID_CHANGEPARAMETER, TCPIP_E_INV_ARG);
    }
    else if (NULL_PTR == ParameterValue)
    {
        TCPIP_DET(TCPIP_SID_CHANGEPARAMETER, TCPIP_E_PARAM_POINTER);
    }
    else
#endif /* STD_ON == TCPIP_DEV_ERROR_DETECT */
    {
#if (STD_ON == TCPIP_BSDSOCKET_SUPPORT)
        ret = TcpIp_BsdChangeParameter(SocketId, ParameterId, ParameterValue);
#else  /* STD_ON != TCPIP_BSDSOCKET_SUPPORT */
        ret = TcpIp_InnerChangeParameter(SocketId, ParameterId, ParameterValue);
#endif /* STD_ON == TCPIP_BSDSOCKET_SUPPORT */
    }

    return ret;
}

/***********************************************************************************************************************
 * Service ID[hex]:     0x10
 * Sync/Async:          Synchronous
 * Reentrancy:          Reentrant
 * Parameters (in):     LocalAddrId Local address identifier referring to the local IP address which shall be obtained.
 * Parameters(inout):   IpAddrPtr: Pointer to a struct where the IP address shall be stored.The struct member domain
 *                      shall be set to the desired.
 *                      TcpIp_DomainType: and it shall be ensured that the struct is large enough to store an address
 *                      of the selected type (INET or INET6).Struct members not related to the IP address are of
 *                      arbitrary value and shall not be used.
 *                      DefaultRouterPtr: Pointer to struct where the IP address of the default router(gateway) is
 *                      stored (struct member "port" is not used and of arbitrary value). The struct must be of the
 *                      same type and size as IpAddrPtr.
 * Parameters (out):    NetmaskPtr: Pointer to memory where Network mask of IPv4 address or address prefix of IPv6
 *                      address in CIDR Notation is stored
 * Return value:        Std_ReturnType Result of operation
 *                      E_OK: The request was successful
 *                      E_NOT_OK: The request was not successful, e.g. domain in IpAddrPtr and the local domain type do
 *                      not match
 * Description:         Obtains the local IP address actually used by LocalAddrId, the netmask and default router
 ***********************************************************************************************************************/
FUNC(Std_ReturnType, TCPIP_CODE)
TcpIp_GetIpAddr(
    TcpIp_LocalAddrIdType LocalAddrId,
    TcpIp_SockAddrType* IpAddrPtr,
    uint8* NetmaskPtr,
    TcpIp_SockAddrType* DefaultRouterPtr)
{
    Std_ReturnType ret = E_NOT_OK;
#if (STD_ON == TCPIP_DEV_ERROR_DETECT)

    if (TCPIP_STATE_INIT != TcpIp_InitState)
    {
        TCPIP_DET(TCPIP_SID_GETIPADDR, TCPIP_E_NOTINIT);
    }
    else if ((NULL_PTR == IpAddrPtr) || (NULL_PTR == NetmaskPtr) || (NULL_PTR == DefaultRouterPtr))
    {
        TCPIP_DET(TCPIP_SID_GETIPADDR, TCPIP_E_PARAM_POINTER);
    }
    else
#endif /* STD_ON == TCPIP_DEV_ERROR_DETECT */
    {
#if (STD_ON == TCPIP_BSDSOCKET_SUPPORT)
        ret = TcpIp_BsdGetIpAddr(LocalAddrId, IpAddrPtr, NetmaskPtr, DefaultRouterPtr);
#else  /* STD_ON != TCPIP_BSDSOCKET_SUPPORT */
        TcpIp_SockAddrType netMaskAdr = {0};
        /* The last three parameters can be replaced by structures */
        ret = TcpIp_InnerGetIpAddr(LocalAddrId, IpAddrPtr, &netMaskAdr, DefaultRouterPtr);
        TcpIp_NetMaskInnerToExt(TcpIp_PbCfgPtr->LocalAdrPtr[LocalAddrId].DomainType, netMaskAdr.addr, NetmaskPtr);
#endif /* STD_ON == TCPIP_BSDSOCKET_SUPPORT */
    }

    return ret;
}

/***********************************************************************************************************************
 * Service ID[hex]:     0x11
 * Sync/Async:          Synchronous
 * Reentrancy:          Non Reentrant
 * Parameters (in):     LocalAddrId Local address identifier implicitely specifing the EthIf controller for which the
 *                      physical address shall be obtained.
 * Parameters(inout):   None
 * Parameters (out):    PhysAddrPtr Pointer to the memory where the physical source address (MAC address) in network
 *                      byte order is stored
 * Return value:        Std_ReturnType Result of operation
 *                      E_OK The request was successful
 *                      E_NOT_OK The request was not successful, e.g. no unique Ctrl specified via IpAddrId.
 * Description:         Obtains the physical source address used by the EthIf controller implicitly specified via
 *                      LocalAddrId.
 ***********************************************************************************************************************/
FUNC(Std_ReturnType, TCPIP_CODE)
TcpIp_GetPhysAddr(TcpIp_LocalAddrIdType LocalAddrId, uint8* PhysAddrPtr)
{
    Std_ReturnType ret = E_NOT_OK;
#if (STD_ON == TCPIP_DEV_ERROR_DETECT)

    if (TCPIP_STATE_INIT != TcpIp_InitState)
    {
        TCPIP_DET(TCPIP_SID_GETPHYSADDR, TCPIP_E_NOTINIT);
    }
    else if (NULL_PTR == PhysAddrPtr)
    {
        TCPIP_DET(TCPIP_SID_GETPHYSADDR, TCPIP_E_PARAM_POINTER);
    }
    else if (LocalAddrId >= TCPIP_LOCAL_ADR_NUM)
    {
        TCPIP_DET(TCPIP_SID_GETPHYSADDR, TCPIP_E_INV_ARG);
    }
    else
#endif /*STD_ON == TCPIP_DEV_ERROR_DETECT*/
    {
#if (TCPIP_CONTROLLER_NUM > 0)
#if (STD_ON == TCPIP_BSDSOCKET_SUPPORT)

#else  /* STD_ON != TCPIP_BSDSOCKET_SUPPORT */
        EthIf_GetPhysAddr(TcpIp_PbCfgPtr->LocalAdrPtr[LocalAddrId].CtrlRef, PhysAddrPtr);
        ret = E_OK;
#endif /* STD_ON == TCPIP_BSDSOCKET_SUPPORT */
#endif /* TCPIP_CONTROLLER_NUM > 0 */
    }

    return ret;
}

/***********************************************************************************************************************
 * Service ID[hex]:     0x16
 * Sync/Async:          Synchronous
 * Reentrancy:          Non Reentrant
 * Parameters (in):     CtrlIdx EthIf controller index to identify the related ARP/NDP table.
 *                      IpAddrPtr specifies the IP address for which the physical address shall be retrieved.
 *                      initRes specifies if the address resolution shall be initiated (TRUE) or not (FALSE) in case the
 *                      physical address related to the specified IP address is currently unknown.
 * Parameters(inout):   None
 * Parameters (out):    PhysAddrPtr Pointer to the memory where the physical address (MAC address) related to the
 *                      specified IP address is stored in network byte order.
 * Return value:        TcpIp_ReturnType TCPIP_E_OK: specified IP address resolved, physical address provided via
 *                      PhysAddrPtr TCPIP_E_PHYS_ADDR_MISS: physical address currently unknown (address resolution
 *                      initiated if initRes set to TRUE)
 * Description:         TcpIp_GetRemotePhysAddr queries the IP/physical address translation table specified by CtrlIdx
 *                      and returns the physical address related to the IP address specified by IpAddrPtr. In case no
 *                      physical address can be retrieved and parameter initRes is TRUE, address resolution for the
 *                      specified IP address is initiated on the local network.
 ***********************************************************************************************************************/
FUNC(TcpIp_ReturnType, TCPIP_CODE)
TcpIp_GetRemotePhysAddr(uint8 CtrlIdx, const TcpIp_SockAddrType* IpAddrPtr, uint8* PhysAddrPtr, boolean initRes)
{
    TcpIp_ReturnType ret = TCPIP_E_NOT_OK;
#if (STD_ON == TCPIP_DEV_ERROR_DETECT)

    if (TCPIP_STATE_INIT != TcpIp_InitState)
    {
        TCPIP_DET(TCPIP_SID_GETREMOTEPHYSADDR, TCPIP_E_NOTINIT);
    }
    else if ((NULL_PTR == IpAddrPtr) || (NULL_PTR == PhysAddrPtr))
    {
        TCPIP_DET(TCPIP_SID_GETREMOTEPHYSADDR, TCPIP_E_PARAM_POINTER);
    }
#if (TCPIP_CONTROLLER_NUM > 0u)
    else if (
        (CtrlIdx > TcpIp_PbCfgPtr->ethIfCtrlMax)
#if (TCPIP_CONTROLLER_NUM > 1u)
        || (TcpIp_PbCfgPtr->EthIfCtrlRefMapping[CtrlIdx] >= TCPIP_CONTROLLER_NUM)
#endif /* TCPIP_CONTROLLER_NUM > 1u */
    )
    {
        TCPIP_DET(TCPIP_SID_GETREMOTEPHYSADDR, TCPIP_E_INV_ARG);
    }
#endif /* TCPIP_CONTROLLER_NUM > 0u */
    else
#endif /*STD_ON == TCPIP_DEV_ERROR_DETECT*/
    {
#if (TCPIP_CONTROLLER_NUM > 0u)
#if (STD_ON == TCPIP_BSDSOCKET_SUPPORT)

#else /* STD_ON != TCPIP_BSDSOCKET_SUPPORT */
#if (TCPIP_SC3 == TCPIP_SCALABILITY_CLASS)

        if (TCPIP_AF_INET == IpAddrPtr->domain)
#endif /* TCPIP_SC3 == TCPIP_SCALABILITY_CLASS*/
        {
#if ((TCPIP_SC1 == TCPIP_SCALABILITY_CLASS) || (TCPIP_SC3 == TCPIP_SCALABILITY_CLASS))
            /* used arp */
#if (TCPIP_CONTROLLER_NUM == 1u)
            ret = TcpIp_GetRemotePhysAddrByArp(0u, IpAddrPtr, PhysAddrPtr, initRes);
#else
            ret = TcpIp_GetRemotePhysAddrByArp(
                TcpIp_PbCfgPtr->EthIfCtrlRefMapping[CtrlIdx],
                IpAddrPtr,
                PhysAddrPtr,
                initRes);
#endif /* TCPIP_CONTROLLER_NUM == 1u */
#endif /* TCPIP_SC1 == TCPIP_SCALABILITY_CLASS || TCPIP_SC3 == TCPIP_SCALABILITY_CLASS */
        }

#if (TCPIP_SC3 == TCPIP_SCALABILITY_CLASS)
        else
#endif /* TCPIP_SC3 == TCPIP_SCALABILITY_CLASS */
        {
#if ((TCPIP_SC2 == TCPIP_SCALABILITY_CLASS) || (TCPIP_SC3 == TCPIP_SCALABILITY_CLASS))
            /* used ndp ,now is not support */
#endif /* TCPIP_SC1 == TCPIP_SCALABILITY_CLASS || TCPIP_SC3 == TCPIP_SCALABILITY_CLASS */
        }
#endif /* STD_ON == TCPIP_BSDSOCKET_SUPPORT */

#endif /* TCPIP_CONTROLLER_NUM > 0u */
    }

    return ret;
}

#if (STD_ON == TCPIP_UDP_ENABLED)
/***********************************************************************************************************************
 * Service ID[hex]:     0x12
 * Sync/Async:          Synchronous
 * Reentrancy:          Reentrant for different SocketIds. Non reentrant for the same SocketId.
 * Parameters (in):     SocketId: Socket identifier of the related local socket resource.
 *                      DataPtr: Pointer to a linear buffer of TotalLength bytes containing the data to be transmitted.
 *                      In case DataPtr is a NULL_PTR, TcpIp shall retrieve data from upper layer
 *                      via callback <Up>_CopyTxData().
 *                      RemoteAddrPtr: IP address and port of the remote host to transmit to.
 *                      TotalLength: indicates the payload size of the UDP datagram.
 * Parameters(inout):   None
 * Parameters (out):    None
 * Return value:        Std_ReturnType E_OK: UDP message has been forwarded to EthIf for transmission.
 *                      E_NOT_OK: UDP message could not be sent because of a permanent error,e.g. message is too long.
 * Description:         This service transmits data via UDP to a remote node. The transmission of the data is
 *                      immediately performed with this function call by forwarding it to EthIf.
 ***********************************************************************************************************************/
FUNC(Std_ReturnType, TCPIP_CODE)
TcpIp_UdpTransmit(
    VAR(TcpIp_SocketIdType, AUTOMATIC) SocketId,
    P2CONST(uint8, AUTOMATIC, TCPIP_APPL_CONST) DataPtr,
    P2CONST(TcpIp_SockAddrType, AUTOMATIC, TCPIP_APPL_CONST) RemoteAddrPtr,
    VAR(uint16, AUTOMATIC) TotalLength)
{
    Std_ReturnType ret = E_NOT_OK;
#if (STD_ON == TCPIP_DEV_ERROR_DETECT)

    if (TCPIP_STATE_INIT != TcpIp_InitState)
    {
        TCPIP_DET(TCPIP_SID_UDPTRANSMIT, TCPIP_E_NOTINIT);
    }
    else if (NULL_PTR == RemoteAddrPtr)
    {
        TCPIP_DET(TCPIP_SID_UDPTRANSMIT, TCPIP_E_PARAM_POINTER);
    }
    else if (SocketId >= TCPIP_SOCKET_NUM)
    {
        TCPIP_DET(TCPIP_SID_UDPTRANSMIT, TCPIP_E_INV_ARG);
    }
    else
#endif /* STD_ON == TCPIP_DEV_ERROR_DETECT */
    {
#if (STD_ON == TCPIP_BSDSOCKET_SUPPORT)
        ret = TcpIp_BsdUdpTransmit(SocketId, DataPtr, RemoteAddrPtr, TotalLength);
#else  /* STD_ON != TCPIP_BSDSOCKET_SUPPORT */
        if ((NULL_PTR != DataPtr) || (0u == TotalLength))
        {
            /* direct transmit */
            ret = TcpIp_InnerUdpTransmit(SocketId, DataPtr, RemoteAddrPtr, TotalLength);
        }
        else
        {
            /* shall copy data from upper layer */
            ret = TcpIp_InnerCopyUdpTransmit(SocketId, RemoteAddrPtr, TotalLength);
        }
#endif /* STD_ON == TCPIP_BSDSOCKET_SUPPORT */
    }

    return ret;
}
#endif /* STD_ON == TCPIP_UDP_ENABLED */

#if (STD_ON == TCPIP_TCP_ENABLED)
/***********************************************************************************************************************
 * Service ID[hex]:     0x13
 * Sync/Async:          Asynchronous
 * Reentrancy:          Reentrant for different SocketIds. Non reentrant for the same SocketId.
 * Parameters (in):     SocketId: Socket identifier of the related local socket resource.
 *                      DataPtr: Pointer to a linear buffer of AvailableLength bytes containing the data to be
 *                      transmitted.In case DataPtr is a NULL_PTR, TcpIp shall retrieve data from upper layer via
 *                      callback <Up>_CopyTxData().
 *                      AvailableLength: Available data for transmission in bytes.
 *                      ForceRetrieve: This parameter is only valid if DataPtr is a NULL_PTR.Indicates how the TCP/IP
 *                      stack retrieves data from upper layer if DataPtr is a NULL_PTR.
 *                      TRUE: the whole data indicated by availableLength shall be retrieved from the upper layer via
 *                      one or multiple <Up>_CopyTxData() calls within the context of this transmit function.
 *                      FALSE: The TCP/IP stack may retrieve up to availableLength data from the upper layer. It is
 *                      allowed to retrieve less than availableLength bytes. Note: Not retrieved data will be provided
 *                      by upper layer with the next call to TcpIp_TcpTransmit (along with new data if available).
 * Parameters(inout):   None
 * Parameters (out):    None
 * Return value:        Std_ReturnType E_OK: The request has been accepted
 *                      E_NOT_OK: The request has not been accepted, e.g. due to a lack of buffer space or the socket
 *                      is not connected.
 * Description:         This service requests transmission of data via TCP to a remote node. The transmission of the
 *                      data is decoupled.
 * Note:                The TCP segment(s) are sent dependent on runtime factors (e.g. receive window) and configuration
 *                      parameter (e.g. Nagle algorithm) .
 ***********************************************************************************************************************/
FUNC(Std_ReturnType, TCPIP_CODE)
TcpIp_TcpTransmit(
    VAR(TcpIp_SocketIdType, AUTOMATIC) SocketId,
    P2CONST(uint8, AUTOMATIC, TCPIP_APPL_CONST) DataPtr,
    VAR(uint32, AUTOMATIC) AvailableLength,
    VAR(boolean, AUTOMATIC) ForceRetrieve)
{
    Std_ReturnType ret = E_NOT_OK;
#if (STD_ON == TCPIP_DEV_ERROR_DETECT)

    if (TCPIP_STATE_INIT != TcpIp_InitState)
    {
        TCPIP_DET(TCPIP_SID_TCPTRANSMIT, TCPIP_E_NOTINIT);
    }
    else if (SocketId >= TCPIP_SOCKET_NUM)
    {
        TCPIP_DET(TCPIP_SID_TCPTRANSMIT, TCPIP_E_INV_ARG);
    }
    else
#endif /* STD_ON == TCPIP_DEV_ERROR_DETECT */
    {
#if (STD_ON == TCPIP_BSDSOCKET_SUPPORT)
        ret = TcpIp_BsdTcpTransmit(SocketId, DataPtr, AvailableLength, ForceRetrieve);
#else  /* STD_ON != TCPIP_BSDSOCKET_SUPPORT */
        if (0u < AvailableLength)
        {
            uint16 totLen = (AvailableLength <= 0xffffu) ? (uint16)AvailableLength : 0xffffu;

            if (NULL_PTR != DataPtr)
            {
                /* direct transmit */
                ret = TcpIp_InnerTcpTransmit(SocketId, DataPtr, totLen);
            }
            else
            {
                /* shall copy data from upper layer */
                ret = TcpIp_InnerCopyTcpTransmit(SocketId, totLen, ForceRetrieve);
            }
        }
#endif /* STD_ON == TCPIP_BSDSOCKET_SUPPORT */
    }

    return ret;
}
#endif /*STD_ON == TCPIP_TCP_ENABLED*/

/***********************************************************************************************************************
 * Service ID[hex]:     0x14
 * Sync/Async:          Synchronous
 * Reentrancy:          Non Reentrant
 * Parameters (in):     CtrlIdx: Index of the EthIf controller.
 *                      FrameType: frame type of received Ethernet frame
 *                      IsBroadcast: parameter to indicate a broadcast frame Specification of TCP/IP Stack
 *                      PhysAddrPtr: pointer to Physical source address (MAC address in network byte order) of
 *                      received Ethernet frame
 *                      DataPtr: Pointer to payload of the received Ethernet frame (i.e. Ethernet header is not
 *                      provided).
 *                      LenByte: Length of received data.
 * Parameters(inout):   None
 * Parameters (out):    None
 * Return value:        None
 * Description:         By this API service the TCP/IP stack gets an indication and the data of a received frame.
 ***********************************************************************************************************************/
FUNC(void, TCPIP_CODE)
TcpIp_RxIndication(
    VAR(uint8, AUTOMATIC) CtrlIdx,
    VAR(Eth_FrameType, AUTOMATIC) FrameType,
    VAR(boolean, AUTOMATIC) IsBroadcast,
    P2CONST(uint8, AUTOMATIC, TCPIP_APPL_CONST) PhysAddrPtr,
    P2CONST(uint8, AUTOMATIC, TCPIP_APPL_DATA) DataPtr,
    VAR(uint16, AUTOMATIC) LenByte)
{
    TCPIP_UNUSED_ARG(PhysAddrPtr);
#if (STD_ON == TCPIP_DEV_ERROR_DETECT)

    if (TCPIP_STATE_INIT != TcpIp_InitState)
    {
        TCPIP_DET(TCPIP_SID_RXINDICATION, TCPIP_E_NOTINIT);
    }
    else
#endif /* STD_ON == TCPIP_DEV_ERROR_DETECT */
    {
#if (TCPIP_CONTROLLER_NUM > 0u)
#if (STD_ON == TCPIP_BSDSOCKET_SUPPORT)

#else /* STD_ON != TCPIP_BSDSOCKET_SUPPORT */
        uint8 flag = (((boolean)TRUE == IsBroadcast) ? PBUF_FLAG_LLBCAST : 0u);
        uint8 TcpIpCtrlIdx = 0u;
#if (TCPIP_CONTROLLER_NUM == 1u)
#if defined(TCPIP_PARA_CHECK)
        if (CtrlIdx == TcpIp_PbCfgPtr->ethIfCtrlMax)
#endif /* defined TCPIP_PARA_CHECK */
#else  /* TCPIP_CONTROLLER_NUM > 1u */
        TcpIpCtrlIdx = TcpIp_PbCfgPtr->EthIfCtrlRefMapping[CtrlIdx];
#if defined(TCPIP_PARA_CHECK)
        if (TcpIpCtrlIdx < TCPIP_CONTROLLER_NUM)
#endif /* defined(TCPIP_PARA_CHECK) */
#endif /* TCPIP_CONTROLLER_NUM == 1u */
        {
            TcpIp_InnerRxIndication(TcpIpCtrlIdx, FrameType, flag, DataPtr, LenByte);
        }
#endif /* STD_ON == TCPIP_BSDSOCKET_SUPPORT */
#endif /* TCPIP_CONTROLLER_NUM > 0u */
    }
}

/***********************************************************************************************************************
 * Service ID[hex]:         0x15
 * Description:             Schedules the TCP/IP stack. (Entry point for scheduling)
 ***********************************************************************************************************************/
FUNC(void, TCPIP_CODE)
TcpIp_MainFunction(void)
{
#if (STD_ON == TCPIP_INITIALIZATION_AVAILABLE)

    if (TCPIP_STATE_INIT == TcpIp_InitState)
#endif /* STD_ON == TCPIP_INITIALIZATION_AVAILABLE */
    {
#if (STD_ON == TCPIP_BSDSOCKET_SUPPORT)
        TcpIp_BsdMainFunction();
#else /* STD_ON != TCPIP_BSDSOCKET_SUPPORT */
#if defined(TCPIP_SUUPORT_CTRL_MAINHANDLE)
        TcpIp_ControlPollMainHandle();
#endif /* defined(TCPIP_SUUPORT_CTRL_MAINHANDLE */
#if (TCPIP_SOCKET_NUM > 0u)
        TcpIp_SocketPollMainHandle();
#endif /* TCPIP_TCP_SOCKET_MAX > 0u */
        TcpIp_PeriodTimerMainHandle();
#endif /* STD_ON == TCPIP_BSDSOCKET_SUPPORT */
    }
}

/***********************************************************************************************************************
 * Service ID[hex]:     0x03
 * Sync/Async:          Synchronous
 * Reentrancy:          Reentrant
 * Parameters (in):     Domain: IP address family.
 *                      Protocol: Socket protocol as sub-family of parameter type.
 * Parameters(inout):   None
 * Parameters (out):    SocketIdPtr: Pointer to socket identifier representing the requested socket.This socket
 *                      identifier must be provided for all further API calls which requires a SocketId.
 *                      Note: SocketIdPtr is only valid if return value is E_OK.
 * Return value:        Std_ReturnType Result of operation
 *                      E_OK: The request has been accepted
 *                      E_NOT_OK: The request has not been accepted: no free socket
 * Description:         By this API service the TCP/IP stack is requested to allocate a new socket.Note: Each accepted
 *                      incoming TCP connection also allocates a socket resource.
 ***********************************************************************************************************************/
FUNC(Std_ReturnType, TCPIP_CODE)
TcpIp_GetSocket(
    VAR(TcpIp_DomainType, AUTOMATIC) Domain,
    VAR(TcpIp_ProtocolType, AUTOMATIC) Protocol,
#if (STD_ON == TCPIP_MUILT_SOCKET_OWNERCFG)
    VAR(uint8, AUTOMATIC) socketOwnererId,
#endif /* STD_ON == TCPIP_MUILT_SOCKET_OWNERCFG */
    P2VAR(TcpIp_SocketIdType, AUTOMATIC, TCPIP_APPL_DATA) SocketIdPtr)
{
    Std_ReturnType ret = E_NOT_OK;
#if (STD_ON == TCPIP_DEV_ERROR_DETECT)

    if (TCPIP_STATE_INIT != TcpIp_InitState)
    {
        TCPIP_DET(TCPIP_SID_UP_GETSOCKET, TCPIP_E_NOTINIT);
    }
    else if (NULL_PTR == SocketIdPtr)
    {
        TCPIP_DET(TCPIP_SID_UP_GETSOCKET, TCPIP_E_PARAM_POINTER);
    }
    else if (NULL_PTR == TcpIp_LCfg.SocketOwnerLCfgPtr)
    {
        TCPIP_DET(TCPIP_SID_UP_GETSOCKET, TCPIP_E_INV_ARG);
    }
    else
#endif /* STD_ON == TCPIP_DEV_ERROR_DETECT */
    {
#if (STD_ON == TCPIP_BSDSOCKET_SUPPORT)
        ret = TcpIp_BsdGetSocket(
            Domain,
            Protocol,
#if (STD_ON == TCPIP_MUILT_SOCKET_OWNERCFG)
            socketOwnererId,
#endif /* STD_ON == TCPIP_MUILT_SOCKET_OWNERCFG */
            SocketIdPtr);
#else /* STD_ON != TCPIP_BSDSOCKET_SUPPORT */
#if (STD_ON == TCPIP_MUILT_SOCKET_OWNERCFG)
        const TcpIp_SocketOwnerLCfgType* upSocketApiCfgPtr = &TcpIp_LCfg.SocketOwnerLCfgPtr[socketOwnererId];
#else  /* STD_ON != TCPIP_MUILT_SOCKET_OWNERCFG */
        const TcpIp_SocketOwnerLCfgType* upSocketApiCfgPtr = TcpIp_LCfg.SocketOwnerLCfgPtr;
#endif /* STD_ON == TCPIP_MUILT_SOCKET_OWNERCFG */
#if defined(TCPIP_CHECK)

        if (NULL_PTR != upSocketApiCfgPtr)
#endif /* defined(TCPIP_CHECK) */
        {
#if (STD_ON == TCPIP_TCP_ENABLED)

            if (Protocol == TCPIP_IPPROTO_TCP)
            {
                ret = TcpIp_MallocTcpSocketId(Domain, upSocketApiCfgPtr, SocketIdPtr);
            }

#endif /* STD_ON == TCPIP_TCP_ENABLED */
#if (STD_ON == TCPIP_UDP_ENABLED)

            if (Protocol == TCPIP_IPPROTO_UDP)
            {
                ret = TcpIp_MallocUdpSocketId(Domain, upSocketApiCfgPtr, SocketIdPtr);
            }

#endif /* STD_ON == TCPIP_UDP_ENABLED */
        }

#if defined(TCPIP_CHECK)
        else
        {
            TCPIP_CHECK_OUTPUT("not socket owner config");
        }

#endif /* defined(TCPIP_CHECK) */
#endif /* STD_ON == TCPIP_BSDSOCKET_SUPPORT */
    }

    return ret;
}
#define TCPIP_STOP_SEC_CODE
#include "TcpIp_MemMap.h"
